package newMap
{
	import com.greensock.TweenLite;
	import com.greensock.TweenMax;
	import fl.transitions.easing.None;
	import fl.transitions.easing.Strong;
	import fl.transitions.Tween;
	import fl.transitions.TweenEvent;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.PixelSnapping;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.events.ProgressEvent;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.getDefinitionByName;
	import flash.utils.getTimer;
	import flash.utils.Timer;
	import org.casalib.events.LoadEvent;
	import org.casalib.load.ImageLoad;
	
	/**
	 * ...
	 * @author ...
	 */
	
	public class LoadMap extends Sprite 
	{
		private var _worldMapBmp		: Bitmap;
		private var _worldMapBmd		: BitmapData;
		private var _mapSprite			: Sprite;
		private var _worldMapURL		: String 	= "assets/WorldMap.swf";
		private var _worldMapBigURL		: String 	= "assets/NEW_map_size_cropped_big.jpg";
		private var _worldMapSmallURL	: String 	= "assets/NEW_map_size_cropped_small.jpg";
		private var _imageLoadBig		: Loader;
		private var _imageLoadSmall		: Loader;
		private var _scaleMapSmall		: Number;
		private var _posX				: Number;
		private var _posY				: Number;
		private var _imageBigSize		: Rectangle = new Rectangle(0, 0, 8033, 3831);
		private var _imageSmallSize		: Rectangle = new Rectangle(0, 0, 1246, 594);
		private var _tweenDurationZoom	: uint  	= 2;
		private var _tweenDurationSwap	: uint  	= 1;
		private var _tweenMethod		: Function	= Strong.easeInOut;
		private var _zoomed				: Boolean	= false;
		private var _croppedImage		: Bitmap;
		private var _vSpriteRegion		: Vector.<Sprite>;
		private var _tBefore:int;
		
		public function LoadMap() 
		{
			super();
			
			_scaleMapSmall = 4;
			_posX = 500;
			_posY = 100;
			_vSpriteRegion = new Vector.<Sprite>();
			
			_loadMap();
		}
		
		private function _loadMap():void 
		{
			_imageLoadSmall = new Loader();
			_imageLoadSmall.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, _onProgressStatus);
			_imageLoadSmall.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderSmallReady);

			var fileRequest:URLRequest = new URLRequest(_worldMapSmallURL);
			_imageLoadSmall.load(fileRequest);
		}
		
		public function _onProgressStatus(e:ProgressEvent):void
		{      
			//trace(e.bytesLoaded, e.bytesTotal); 
		}

		public function onLoaderSmallReady(e:Event):void
		{          
			addChild(_imageLoadSmall);
			_imageLoadSmall.addEventListener(MouseEvent.CLICK, _onMouseClickSmallMap, false, 0, true);
		
			_imageLoadBig = new Loader();
			_imageLoadBig.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, _onProgressStatus, false, 0, true);
			_imageLoadBig.contentLoaderInfo.addEventListener(Event.COMPLETE, _onLoaderBigReady, false, 0, true);
			var fileRequest:URLRequest = new URLRequest(_worldMapBigURL);
			_imageLoadBig.load(fileRequest);
			
			_createRegion();
		}
		
		private function _onMouseClickSmallMap(e:MouseEvent):void 
		{
			trace(this, "_onMouseClickSmallMap _zoomed", _zoomed);
			if (_zoomed)
			{
				removeChild(_croppedImage);
				_croppedImage = null;
				_zoomOut();
			}
		}
		
		private function _onMapSmallZoomInComplete(e:TweenEvent):void 
		{
			trace(this, "_onMapSmallZoomInComplete");
			
			//if _cropImage runs here, it takes more time(roughly 0.7 sec) load the cropped high resolution image.
			//_cropImage();
			
			_croppedImage.alpha = 1;
			_zoomed = true;
			addChild(_croppedImage);
			//var __tw:Tween = new Tween(_croppedImage, "alpha", _tweenMethod, 0, 1, _tweenDurationSwap, true);
			//__tw.addEventListener(TweenEvent.MOTION_FINISH, _onTweenMotionFinish, false, 0, true);
			
			var _tAfter:int = getTimer();
			trace(this, "Time taken:", _tAfter - _tBefore);
		}
		
		private function _createRegion():void 
		{
			addChild(_createBlock(150, 180, 200, 130));
			addChild(_createBlock(500, 100, 130, 120));
		}
		
		private function _createBlock(x:Number, y:Number, width:Number, height:Number):Sprite
		{
			var __s:Sprite = new Sprite;
			__s.graphics.beginFill(0x000000, 0.5);
			__s.graphics.drawRect(0, 0, width, height);
			__s.x = x;
			__s.y = y;
			__s.graphics.endFill();
			__s.addEventListener(MouseEvent.CLICK, _onRegionClick, false, 0, true);
			_vSpriteRegion.push(__s);
			return __s;
		}
		
		private function _onRegionClick(e:MouseEvent):void 
		{
			if (!_zoomed)
			{
				_visibilityVector(_vSpriteRegion, false);
				var __s:Sprite = Sprite(e.currentTarget);
				//trace(this, "_onRegionClick", __s.x, __s.y, __s.width, __s.height);
				_zoomIn(__s.x, __s.y);
			}
		}
		
		private function _zoomIn(x:Number,y:Number):void 
		{
			_tBefore = getTimer();
			_posX = x;
			_posY = y;
			
			var __twScaleX:Tween = new Tween(_imageLoadSmall, "scaleX", _tweenMethod, 1, _scaleMapSmall, _tweenDurationZoom, true);
			var __twScaleY:Tween = new Tween(_imageLoadSmall, "scaleY", _tweenMethod, 1, _scaleMapSmall, _tweenDurationZoom, true);
			var __twPosX:Tween = new Tween(_imageLoadSmall, "x", _tweenMethod, 0, -_posX*_scaleMapSmall, _tweenDurationZoom, true);
			var __twPosY:Tween = new Tween(_imageLoadSmall, "y", _tweenMethod, 0, -_posY*_scaleMapSmall, _tweenDurationZoom, true);
			__twScaleX.addEventListener(TweenEvent.MOTION_FINISH, _onMapSmallZoomInComplete, false, 0, true);
			
			_cropImage();
		}
		
		private function _cropImage():void 
		{
			var __scale:Number= _scaleMapSmall * _imageSmallSize.width / _imageBigSize.width
			_croppedImage = _crop(_posX * _imageBigSize.width / _imageSmallSize.width, _posY * _imageBigSize.height / _imageSmallSize.height, _imageSmallSize.width /__scale, _imageSmallSize.height /__scale, DisplayObject(_imageLoadBig));
			_croppedImage.alpha = 0;
			_croppedImage.scaleX = _croppedImage.scaleY = __scale;
		}
		
		private function _zoomOut():void 
		{
			var __twScaleX:Tween = new Tween(_imageLoadSmall, "scaleX", _tweenMethod, _scaleMapSmall, 1, _tweenDurationZoom, true);
			var __twScaleY:Tween = new Tween(_imageLoadSmall, "scaleY", _tweenMethod, _scaleMapSmall, 1, _tweenDurationZoom, true);
			var __twPosX:Tween = new Tween(_imageLoadSmall, "x", _tweenMethod, -_posX*_scaleMapSmall,0,  _tweenDurationZoom, true);
			var __twPosY:Tween = new Tween(_imageLoadSmall, "y", _tweenMethod, -_posY*_scaleMapSmall, 0, _tweenDurationZoom, true);
			__twScaleX.addEventListener(TweenEvent.MOTION_FINISH, _onMapZoomOutComplete, false, 0, true);
		}
		
		private function _onMapZoomOutComplete(e:TweenEvent):void 
		{
			_visibilityVector(_vSpriteRegion, true);
			_zoomed = false;
		}
		
		private function _crop( _x:Number, _y:Number, _width:Number, _height:Number, displayObject:DisplayObject = null):Bitmap
		{
			try 
			{
				//trace(this, "crop", _x, _y, _width, _height);
				var __cropArea:Rectangle = new Rectangle( 0, 0, _width, _height );
				var __croppedBitmap:Bitmap = new Bitmap( new BitmapData( _width, _height ), PixelSnapping.ALWAYS, true );
				__croppedBitmap.bitmapData.draw( (displayObject!=null) ? displayObject : stage, new Matrix(1, 0, 0, 1, -_x, -_y) , null, null, __cropArea, true );
			}
			catch (err:Error){trace(this, err.message);}
			finally { return __croppedBitmap; }
		}
		
		private function _onTweenMotionFinish(e:TweenEvent):void 
		{
			_zoomed = true;
		}
		
		private function _onLoaderBigReady(e:Event):void 
		{
			trace(this, "_onLoaderBigReady");
		}
		
		private static function _visibilityVector(vector:Vector.<Sprite>, boolean:Boolean):void
		{
			for each (var __s:Sprite in vector)
			{
				__s.visible = boolean;
			}
		}
		
	}

}